#ifndef PP_TOKEN_H
#define PP_TOKEN_H

#include <string>
#include <vector>
#include <cstdint>
#include <memory>

#define TOKEN_TYPE_TEXT         "text"
#define TOKEN_TYPE_OP           "op"
#define TOKEN_TYPE_COMMENT      "comment"
#define TOKEN_TYPE_TAGS         "tags"
#define TOKEN_TYPE_QUOTES       "quotes"

namespace pp
{
    class TokenInfo
    {
    private:
        std::string m_sType;    // Toke type
        std::string m_sValue;   // Token value
    public:
        TokenInfo(const std::string& tokenType, const std::string& tokenValue) : m_sType(tokenType), m_sValue(tokenValue) {}

        const std::string& GetTokenType() const {return m_sType;}
        const std::string& GetTokenValue() const {return m_sValue;}
    };

    class Tokenizer
    {
    private:
        typedef void (Tokenizer::*FUNCTOKENSTATE)(uint32_t pos, char ch, const std::string& data);
    private:
        uint32_t m_u32Pos;
        std::string m_sName;
        FUNCTOKENSTATE m_fnState;       // 状态处理函数
        std::vector<std::shared_ptr<TokenInfo> > m_oTokens;
    public:
        Tokenizer();

        // 解析字符串
        std::vector<std::shared_ptr<TokenInfo> >& Parse(const std::string& data);
        // 解析文件
        std::vector<std::shared_ptr<TokenInfo> >& ParseFile(const std::string& fileName);
    private:
        void Reset(); // 重置数据
        void OnTokenStateText(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateSpace(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateComment(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateComment2(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateTags(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateRefer(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateSingleQuotes(uint32_t pos, char ch, const std::string& data);
        void OnTokenStateQuotes(uint32_t pos, char ch, const std::string& data);
    };
};

#endif
